;*******************************************************************************
; Title:	IfTask
; Author:	Philip Ludlam
; Copyright:	(C) Philip Ludlam 2013
; Version:	1.04, 13 Jun 2013
;
; Changes:	Updated for the A9home by Philip Ludlam
;
;*******************************************************************************
; This program is free software; you can redistribute it and/or modify it
; under the terms of the GNU General Public License as published by the Free
; Software Foundation; either version 2 of the License, or (at your option)
; any later version.
;
; This program is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
; FITNESS FOR APARTICULAR PURPOSE. See the GNU General Public License for more
; details.
;
; You should have received a copy of the GNU General Public License along with
; this program; if not, write to the Free Software Foundation, Inc., 59 Temple
; Place - Suite 330, Boston, MA 02111-1307, USA
;
;*******************************************************************************


		TTL	> IfTask

		GET	OSLib:oslib.hdr.OS
		GET	OSLib:oslib.hdr.OSByte
		GET	OSLib:oslib.hdr.OSFSControl
		GET	OSLib:oslib.hdr.TaskManager
		GET	AsmLib2:hdr.RegsBoth
		GET	AsmLib2:hdr.MacrosBoth

arg_task	*	&0
arg_command	*	&4
arg_yes		*	&8
arg_no		*	&C

		AREA	|main|, CODE, READONLY

		ENTRY

;-------------------------------------------------------------------------------

Start		B	Entry			; Entry instruction
		DCD	&79766748		; Magic value 1
		DCD	&216C6776		; Magic value 2
		DCD	End-Start		; Read only size
		DCD	0			; Read/write size
		DCD	32			; 26 or 32 bit build

Entry		MOV	r11, lr			; Store lr in r11

		ADR	r0, args
		MOV	r2, r12			;  to workspace
		SUB	r3, r13, r12		; r3 = size in workspace
		SWI	XOS_ReadArgs
		ADRVS	r0, syntax
		MOVVS	pc, r11

		LDR	r2, [r12, #arg_command]
		CMP	r2, #0
		BEQ	syntax_code

		SUB	r8, r13, r3		; r8 = next free block in workspace

do		LDR	r0, [wp, #arg_task]
		BL	FindTaskHandle
		CMP	r0, #0
		BEQ	do_command_no

do_command_yes
		LDMIA	wp, {r0, r5, r6, r7}
		TEQ	r7, #0
		MOVEQ	r6, #0
		B	do_command

do_command_no
		LDMIA	wp, {r0, r5, r6, r7}
		TEQ	r6, #0
		TEQNE	r7, #0
		MOVNE	r6, r7
		BNE	do_command
		TEQ	r6, #0
		BEQ	exit
		MOV	r5, r6
		MOV	r6, #0

do_command
		MOV	r1, r8
		MOV	r0, r5
		MOV	r2, #32
		BL	copy
		MOVS	r0, r6
		MOV	r2, #0
		BLNE	copy
		STREQB	r2, [r1, #-1]

os_cli
		MOV	r0, r8
		SWI	XOS_CLI

exit
		MOV	pc, r11

error
		SetV
		MOV	pc, r11

copy
		LDRB	r3, [r0], #1
		STRB	r3, [r1], #1
		CMP	r3, #32
		BGE	copy
		STRB	r2, [r1, #-1]
		MOV	pc, lr


;*******************************************************************************
;----f- FindTaskHandle
; Name
;   FindTaskHandle
;
; Purpose
;   This finds the task handle of the task name pointed to by r0
;
; Entry
;   r0 -> name of task
;
; Exit
;   r0 = task handle or 0 for not found
;------
;*******************************************************************************


FindTaskHandle	ROUTINE_SF	"r1-r5"
task$l		#	TaskManager_Task
		END_SF

		MOV	r5, r0				; pointer to name
		MOV	r4, #0				; context
loop$l
		MOV	r0, r4
		ADR	r1, task$l			; block
		MOV	r2, #TaskManager_Task		; get 1 at a time please
		SWI	XTaskManager_EnumerateTasks
		BVS	error$l				; not found if error
		MOVS	r4, r0				; save context
		BMI	error$l				; not found

		LDR	r0, task$l + TaskManager_Task_name
		MOV	r1, r5
		BL	strcmpi				; compare name
		BNE	loop$l

							; found
		LDR	r0, task$l + TaskManager_Task_task
		EXIT

error$l		MOV	r0, #0
		EXIT


;*******************************************************************************
;----f- strcmpi
; Name
;   strcmpi
;
; Purpose
;   Case insensitive comparison
;
; Entry
;   r0 = pointer to one string
;   r1 = pointer to another string
;
; Exit
;   Flags
;     Z            (EQ) set if strings are equal
;     ~Z && (N=V)  (GT) set if r0  string > (greater than) r1  string
;     N<>V         (LT) set if r0  string < (less than) r1  string
;------
;*******************************************************************************


strcmpi		ROUTINE	"r0-r3", EXPORT

strcmpi_loop$l
		LDRB	r2,[r0],#1
		CMP	r2,#32		;turn terminator into 0
		MOVLT	r2,#0
		UpperCase	r2,lr

		LDRB	r3,[r1],#1
		CMP	r3,#32		;turn terminator into 0
		MOVLT	r3,#0
		UpperCase	r3,lr

		CMP	r2,r3
		EXIT	NE

		CMP	r2,#0
		CMPEQ	r3,#0
		BNE	strcmpi_loop$l	;have we reached null for both strings?

		EXIT			;return EQ


syntax_code
		SetV
		ADR	r0, syntax
		MOV	pc, r11

args
		DCB	",,,"
		DCB	0
		ALIGN

syntax
		DCD	0
		DCB	"Syntax: *IfTask <Taskname> <yes command> [<no command>]", 10, 13
		DCB	"or:     *IfTask <Taskname> <command> <yes param> <no param>"
		DCB	0

licence		DCB	" PJL, 2013. Licence: GPL."
		ALIGN

End
		END
